<template>
  <div class="table-filter-cascade">
    <el-cascader
      v-model="vModel"
      :props="cascadeProps"
      :options="cascadedOptions"
      size="small"
      clearable
      collapse-tags
      popper-class="table-filter-cascade-popper"
      @change="change">
    </el-cascader>
  </div>
</template>

<script>
  import {assembleTreeFromArray} from '@/utils';
  import {commonString} from '@/config/string';

  export default {
    name: 'TableFilterCascade',
    model: {
      event: 'change'
    },
    props: {
      value: {
        type: Array,
        default: () => {
          return [];
        }
      },
      options: {
        type: Array,
        default: () => {
          return [];
        }
      },
      dataApi: {
        type: String,
        default: 'areaByPid'
      },
      multiple: {
        type: Boolean,
        default: true
      },
      lazy: {
        type: Boolean,
        default: true
      }
    },
    data() {
      return {
        cascadeProps: {},
        cascadedOptions: [],
        vModel: []
      };
    },
    watch: {
      value: {
        handler() {
          if (this.multiple) {
            this.vModel = this.value;
          } else {
            this.vModel = this.value[0] || [];
          }
        },
        immediate: true
      },
      options: {
        handler() {
          // TODO 需要要求后台返回的 options 结构：{childKey: 'id', parentKey: 'pid'} Henry 2021-01-20 17:10:28
          this.cascadedOptions = assembleTreeFromArray({srcData: this.options, createProperty: true, filter: true});
        },
        immediate: true
      }
    },
    created() {
      this.$EventBus.$on(this.$route.path, () => {
        this.cascadedOptions = [];
      });
      this.initCascadeProps(); // 初始化级联选择器参数
    },
    beforeDestroy() {
      // 组件销毁前需要解绑事件，否则会出现重复触发事件的问题。
      this.$EventBus.$off(this.$route.path);
    },
    methods: {
      initCascadeProps() {
        this.cascadeProps = {
          multiple: this.multiple, // 是否多选
          checkStrictly: true, // 是否严格的遵守父子节点不互相关联
          emitPath: false, // 在选中节点改变时，是否返回由该节点所在的各级菜单的值所组成的数组，若设置 false，则只返回该节点的值
          lazy: this.lazy,
          lazyLoad: this.lazyLoad // 加载动态数据的方法
        };
      },
      lazyLoad(node, resolve) {
        const {data = {}} = node;
        API.table[this.dataApi]({pid: data.id || 0}).then(resp => {
          const {data = []} = resp;
          resolve(data.map(a => {
            const {name = '', id, hasChild = 'N'} = a;
            return {
              ...a,
              value: `${id}`,
              label: name || commonString.unknown,
              leaf: false //hasChild === 'N' // todo 等后台接口返回是否有子级
            };
          }));
        }).catch(err => {
          console.log('err', err)
          resolve([]);
        });
      },
      judgeContain(src = []) {
        let contain = false;
        for (let i = 0; i < value.length; i++) {
          if (value[i].length > src.length &&
            src.every(val => value[i].includes(val))) {
            contain = true;
            break;
          }
        }
        return contain;
      },
      change(value) {
        let destValue = [];
        if (this.multiple) {
          destValue = value;
        } else {
          destValue = [value];
        }
        this.$emit('change', destValue);
      }
    }
  };
</script>

<style scoped>
</style>
